home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Snippets / String Rotation / GetRotatedStringBitmap.c next >
Encoding:
C/C++ Source or Header  |  1995-12-08  |  5.0 KB  |  154 lines  |  [TEXT/R*ch]

  1. /***
  2.  
  3.     GetRotatedStringBitmap
  4.     
  5.     By Guy Fullerton (hedgeboy@kagi.com)
  6.     
  7.     This function takes a pascal string, rotates it 90 degrees in the desired
  8.     direction and passes back a BitMap of the rotated string image.
  9.     
  10.     It is based upon some Apple sample source code called RotateString.  The
  11.     Apple code left some unsightly pixels along the edges of the BitMap,
  12.     so I fixed it.
  13.     
  14.     You are free to use this any way you like.
  15.  
  16. ***/
  17.  
  18.  
  19. #include "GetRotatedStringBitmap.h"
  20.  
  21.  
  22. /******************************/
  23. /*** GetRotatedStringBitmap ***/
  24. /******************************/
  25.  
  26. OSErr GetRotatedStringBitmap( Str255 str, BitMap *destMap, RotationDirection direction )
  27. {
  28.     GrafPort    srcPort;
  29.     BitMap      srcMap;
  30.     char        *srcPtr, *destPtr;
  31.     FontInfo    f;
  32.     short        textHeightBits;
  33.     short        textHeightBytes;
  34.     short        textWidthBits;
  35.     short        textWidthBytes;
  36.     short       row, column;
  37.     short       texFont,texFace,texMode,texSize;
  38.     short       err;
  39.     GrafPtr     savePort;
  40.  
  41.     GetPort(&savePort);
  42.  
  43.     texFont = qd.thePort->txFont;
  44.     texFace = qd.thePort->txFace;
  45.     texMode = qd.thePort->txMode;
  46.     texSize = qd.thePort->txSize;
  47.  
  48.     OpenPort( &srcPort);
  49.     SetPort(&srcPort);
  50.  
  51.     TextFont(texFont);
  52.     TextFace(texFace);
  53.     TextMode(texMode);
  54.     TextSize(texSize);
  55.     GetFontInfo( &f);
  56.  
  57.     // calculate the height bits for the text.  this is equal to the font's ascent plus descent
  58.     textHeightBits = f.ascent + f.descent;// + f.leading;
  59.     
  60.     // calculate the height bytes.  this is the number of bytes just equal to or greater than
  61.     // the number of bits divided by 8
  62.     textHeightBytes = (textHeightBits + 7) / 8;
  63.  
  64.     // calculate the width of the text, in bits
  65.     textWidthBits = StringWidth( str );
  66.     
  67.     // calculate the width bytes just like we did for the height bytes
  68.     textWidthBytes = (textWidthBits + 7) / 8;
  69.         
  70.     // create a new bit map to hold the source text
  71.     srcPort.portBits.baseAddr = NewPtrClear( textWidthBytes * textHeightBits );
  72.     if(    err = MemError() ) return err;
  73.     
  74.     // set up the row bytes and bounds for the source bitmap
  75.     srcPort.portBits.rowBytes = textWidthBytes;
  76.     SetRect( &srcPort.portBits.bounds, 0, 0, textWidthBits, textHeightBits );
  77.     
  78.     // create the new bit map to hold the destination text
  79.     destMap->baseAddr = NewPtrClear( textHeightBytes * textWidthBits );
  80.     if( err = MemError() )
  81.     {
  82.         DisposePtr( srcPort.portBits.baseAddr );
  83.         return err;
  84.     }
  85.     
  86.     // set up the row bytes and bounds for the destination bitmap
  87.     destMap->rowBytes = textHeightBytes;
  88.     SetRect( &destMap->bounds, 0, 0, textHeightBits, textWidthBits );
  89.     
  90.     // draw the text into the source bitmap
  91.     RectRgn( srcPort.visRgn, &srcPort.portBits.bounds );
  92.     MoveTo( 0, f.ascent);  // change 2.0.1 <CKH> was heightBits
  93.     DrawString( str );
  94.     
  95.     srcPtr = srcPort.portBits.baseAddr;     // Start at the Top,Left
  96.     
  97.     if(direction == rotationDirection_CounterClockWise)       // Start at the Bottom,Left
  98.         destPtr = destMap->baseAddr + ((textWidthBits - 1) * textHeightBytes);
  99.     else                                    // Start at the Top,Left
  100.         destPtr = destMap->baseAddr;
  101.  
  102.     for( column = 0; column < textWidthBits; column++ )       /* width is in pixels */
  103.     {
  104.         for( row = 0; row < textHeightBits; row++ )       /* height in pixels, too */
  105.         {
  106.             if( direction == rotationDirection_CounterClockWise )
  107.             {
  108.                 /* We are rotating left ( counter clock-wise ) thus */
  109.                 /*  as we search across the top of the horizontal pixel bit map,    */
  110.                 /*  we write down the right edge of the vertical pixel bit map */
  111.                 
  112.                 if( *(srcPtr                            /* Begin with the upper left corner */
  113.                         + (row * textWidthBytes)        /* Move down a row */
  114.                         + (column >> 3))                /* Go to the first even byte */
  115.                         & (0x80 >> (column & 7)) )        /* calculate a shifted bit position based on the column */
  116.                 {
  117.                     *(destPtr                            /* Begin in the lower left corner */
  118.                         - (column * textHeightBytes)    /* Subtract, move up for each row */
  119.                         + (row >> 3))                    /* Calculate a bit position for the column */
  120.                         |= (0x80 >> (row & 7));            /* Set a bit based on the column */
  121.                 }
  122.             }
  123.             else // clockwise
  124.             {
  125.                 /*  We are rotating right (clock-wise) thus */
  126.                 /*  as we search across the top of the horizontal pixel bit map, */
  127.                 /*  we write down the left edge of the vertical pixel bit map */
  128.                 
  129.                 if( *(srcPtr                        /* Begin with the upper left corner */
  130.                         + (row * textWidthBytes)    /* Move down a row */
  131.                         + (column >> 3))            /* Go to the first even byte */
  132.                         & (0x80 >> (column & 7)) )    /* calculate a shifted bit position based on the column */
  133.                 {
  134.                     *(destPtr                                    /* Begin in the lower left corner */
  135.                         + (column * textHeightBytes)            /* Add, move down for each row */
  136.                         + ((textHeightBits - (row + 1)) >> 3))    /* Calculate a byte position for the column */
  137.                         |= (0x80 >>                                /* Set a bit based on the column */
  138.                             (((textHeightBits - 1) - row) & 7));
  139.                 }
  140.             }
  141.         }
  142.     }
  143.     
  144.     // clean up the used source BitMap, and restore the ports properly
  145.     DisposePtr( srcPort.portBits.baseAddr );
  146.     ClosePort( &srcPort );
  147.     SetPort( savePort );
  148.     
  149.     return( noErr );
  150.  
  151. } /* GetRotatedStringBitmap */
  152.  
  153.  
  154.